﻿using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Text;
using System.Collections.Generic;
using ECBS_Backend.model;

namespace ECBS_Backend.utils
{
    public class HttpUtils
    {
        private IHttpClientFactory httpClientFactory;

        public HttpUtils(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        //---------------------------------发送post请求-------------------------------

        public string Post(RestserviceParam restserviceParam)
        {
            var client = httpClientFactory.CreateClient();
            var content = new StringContent(restserviceParam.Body, Encoding.UTF8, "application/json");
            HttpResponseMessage response = client.PostAsync(restserviceParam.url, content).Result;
            string resultContent = string.Empty;
            if (response.IsSuccessStatusCode)
            {
                resultContent = response.Content.ReadAsStringAsync().Result;
                return resultContent;
            }
            else
            {
                throw new Exception("RestService请求错误！");
            }
        }

        //---------------------------------实际调用的方法-------------------------------

        public string createWeId()
        {
            RequestBody requestBody = new RequestBody(new Dictionary<string, object>(), "createWeId");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            return JsonConvert.DeserializeObject<Dictionary<string, string>>(resp)["respBody"];
        }

        public string registerAuthorityIssuer(string adminWeID, string schoolWeID, string schoolName)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            Dictionary<string, object> transactionArg = new Dictionary<string, object>();
            functionArg.Add("weId", schoolWeID);
            functionArg.Add("name", schoolName);
            transactionArg.Add("invokerWeId", adminWeID);
            RequestBody requestBody = new RequestBody(functionArg, transactionArg, "registerAuthorityIssuer");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            return JsonConvert.DeserializeObject<Dictionary<string, string>>(resp)["respBody"];
        }

        public bool recognizeAuthorityIssuer(string schoolWeID)
        {
            string url = "http://localhost:6021/weid/weid-build-tools/recognizeAuthorityIssuer";
            var client = httpClientFactory.CreateClient();
            var content = new StringContent("weId=" + schoolWeID, Encoding.UTF8, "application/x-www-form-urlencoded");
            HttpResponseMessage response = client.PostAsync(url, content).Result;
            if(!response.IsSuccessStatusCode)
            {
                throw new Exception("认证" + schoolWeID + "失败！");
            }
            return true;
        }

        public bool deRecognizeAuthorityIssuer(string schoolWeID)
        {
            string url = "http://localhost:6021/weid/weid-build-tools/deRecognizeAuthorityIssuer";
            var client = httpClientFactory.CreateClient();
            var content = new StringContent("weId=" + schoolWeID, Encoding.UTF8, "application/x-www-form-urlencoded");
            HttpResponseMessage response = client.PostAsync(url, content).Result;
            if(!response.IsSuccessStatusCode)
            {
                throw new Exception("撤销" + schoolWeID + "失败！");
            }
            return true;
        }

        public bool isRecognized(string schoolWeID)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            functionArg.Add("weId", schoolWeID);
            RequestBody requestBody = new RequestBody(functionArg, "queryAuthorityIssuer");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            var respBody = JsonConvert.DeserializeObject<Dictionary<string, string>>(resp)["respBody"];
            bool isExists = respBody == null;
            if(isExists)
            {
                throw new Exception("该学校未被注册为权威证书发行者！");
            }
            bool isRecognized = JsonConvert.DeserializeObject<Dictionary<string, string>>(respBody)["recognized"] == "true";
            return isRecognized;
        }

        public string createEnrollmentCredential(string schoolWeID, EnrollmentClaim enrollmentClaim)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            Dictionary<string, object> transactionArg = new Dictionary<string, object>();
            functionArg.Add("issuer", schoolWeID);
            // cptId需要提前注册获得
            functionArg.Add("cptId", "1000");
            functionArg.Add("expirationDate", "2100-09-01T12:00:00Z");
            // functionArg.Add("expirationDate", DateTime.Parse(DateTime.Now.ToString("1970-01-01T08:00:00Z")).AddMilliseconds(enrollmentClaim.EnrollTime).ToString("s")+"Z");
            functionArg.Add("claim", enrollmentClaim);
            transactionArg.Add("invokerWeId", schoolWeID);
            RequestBody requestBody = new RequestBody(functionArg, transactionArg, "createCredential");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            return JsonConvert.DeserializeObject<Dictionary<string, object>>(resp)["respBody"].ToString();
        }

        public string createGradeCredential(string schoolWeID, GradeClaim gradeClaim)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            Dictionary<string, object> transactionArg = new Dictionary<string, object>();
            functionArg.Add("issuer", schoolWeID);
            functionArg.Add("cptId", "1000");
            functionArg.Add("expirationDate", "2100-09-01T12:00:00Z");
            functionArg.Add("claim", gradeClaim);
            transactionArg.Add("invokerWeId", schoolWeID);
            RequestBody requestBody = new RequestBody(functionArg, transactionArg, "createCredential");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            return JsonConvert.DeserializeObject<Dictionary<string, object>>(resp)["respBody"].ToString();
        }

        public bool verifyEnrollment(EnrollmentClaim claimNeedVerify, string context)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            functionArg = changeContext(claimNeedVerify, context);
            RequestBody requestBody = new RequestBody(functionArg, "verifyCredential");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            if(JsonConvert.DeserializeObject<Dictionary<string, string>>(resp)["respBody"].Equals("true"))
            {
                return true;
            }
            return false;
        }

        public bool verifyGrade(GradeClaim claimNeedVerify, string context)
        {
            Dictionary<string, object> functionArg = new Dictionary<string, object>();
            functionArg = changeGradeContext(claimNeedVerify, context);
            RequestBody requestBody = new RequestBody(functionArg, "verifyCredential");
            RestserviceParam param = new RestserviceParam(requestBody);
            string resp = Post(param);
            if(JsonConvert.DeserializeObject<Dictionary<string, string>>(resp)["respBody"].Equals("true"))
            {
                return true;
            }
            return false;
        }


        //-----------------------------------工具函数-----------------------------------

        private Dictionary<string, object> changeContext(EnrollmentClaim enrollmentClaim, string context)
        {
            Dictionary<string, object> newArg = JsonConvert.DeserializeObject<Dictionary<string, object>>(context);
            newArg["claim"] = enrollmentClaim;
            return newArg;
        }

        private Dictionary<string, object> changeGradeContext(GradeClaim gradeClaim, string context)
        {
            Dictionary<string, object> newArg = JsonConvert.DeserializeObject<Dictionary<string, object>>(context);
            newArg["claim"] = gradeClaim;
            return newArg;
        }
    }
}
